package server

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"

	// "net/http"

	"fiber/config"
	"fiber/global"
	"fiber/utils"
	"time"
	// "fmt"
)

var (
	level   zapcore.Level // zap 日志等级
	options []zap.Option  // zap 配置项

	month_dir string
)

/*
*
日志初始化
*/
func InitializeLog() *zap.Logger {

	// 获得当前的月份
	month_dir = time.Now().Format("2006-01")

	// 创建日志保存目录
	utils.MakeDir(config.Log.RootDir + "/" + month_dir)

	// 设置日志等级
	setLogLevel()

	if config.Log.ShowLine {
		options = append(options, zap.AddCaller())
	}

	// 初始化 zap
	global.Log = zap.New(getZapCore(), options...)

	return global.Log
}

/*
*
设置日志等级
*/
func setLogLevel() {
	switch config.Log.Level {
	case "debug":
		level = zap.DebugLevel
	case "info":
		level = zap.InfoLevel
	case "warn":
		level = zap.WarnLevel
	case "error":
		level = zap.ErrorLevel
	case "dpanic":
		level = zap.DPanicLevel
	case "panic":
		level = zap.PanicLevel
	case "fatal":
		level = zap.FatalLevel
	default:
		level = zap.InfoLevel
	}

	if config.Log.Debug {
		// 调试模式打开详细输出
		options = append(options, zap.AddStacktrace(level))
	} else {
		// 关闭详细输出
		options = options[0:0]
	}

	options = append(options, zap.Fields())

}

// 扩展 Zap
func getZapCore() zapcore.Core {
	var encoder zapcore.Encoder

	// 调整编码器默认配置
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = func(time time.Time, encoder zapcore.PrimitiveArrayEncoder) {
		encoder.AppendString(time.Format("[" + "2006-01-02 15:04:05.000" + "]"))
	}
	// encoderConfig.EncodeLevel = func(l zapcore.Level, encoder zapcore.PrimitiveArrayEncoder) {
	//     encoder.AppendString(config.App.Env + "." + l.String())
	// }

	// 设置编码器
	if config.Log.Format == "json" {
		encoder = zapcore.NewJSONEncoder(encoderConfig)
	} else {
		encoder = zapcore.NewConsoleEncoder(encoderConfig)
	}

	//  // 获取 info、error日志文件的io.Writer 抽象 getWriter() 在下方实现
	//  infoWriter := getWriter("./logs/demo_info.log")
	//  errorWriter := getWriter("./logs/demo_error.log")
	//  // 最后创建具体的Logger
	//  core := zapcore.NewTee(
	//  zapcore.NewCore(encoder, zapcore.AddSync(infoWriter), infoLevel),
	//  zapcore.NewCore(encoder, zapcore.AddSync(errorWriter), errorLevel),
	//  )
	//  log := zap.New(core, zap.AddCaller()) // 需要传入 zap.AddCaller() 才会显示打日志点的文件名和行数, 有点小坑
	//  errorLogger = log.Sugar()

	return zapcore.NewCore(encoder, getLogWriter(), level)
}

// func getWriter(filename string) io.Writer {
// 	// 生成rotatelogs的Logger 实际生成的文件名 demo.log.YYmmddHH
// 	// demo.log是指向最新日志的链接
// 	// 保存7天内的日志，每1小时(整点)分割一次日志
// 	hook, err := rotatelogs.New(
// 		strings.Replace(filename, ".log", "", -1)+"-%Y%m%d%H%I.log", // 没有使用go风格反人类的format格式
// 		rotatelogs.WithLinkName(filename),
// 		rotatelogs.WithMaxAge(time.Hour*24*7),
// 		rotatelogs.WithRotationTime(time.Minute),
// 	)
// 	if err != nil {
// 		panic(err)
// 	}
// 	return hook
// }

// 使用 lumberjack 作为日志写入器
func getLogWriter() zapcore.WriteSyncer {

	file := &lumberjack.Logger{
		// Filename:   config.Log.RootDir + "/" + month_dir + "/" + time.Now().Format("02") + ".log",
		Filename:   config.Log.RootDir + "/app.log",
		MaxSize:    config.Log.MaxSize,
		MaxBackups: config.Log.MaxBackups,
		MaxAge:     config.Log.MaxAge,
		Compress:   config.Log.Compress,
	}

	return zapcore.AddSync(file)
}
